<template>
	<div class="marquee-wrapper">
		<!-- 可视区域，固定显示3条数据 -->
		<div class="marquee-viewport" ref="viewport">
			<!-- 滚动内容区 -->
			<div class="marquee-content" ref="content" :style="{ transform: `translateY(-${scrollPosition}px)` }">
				<!-- 渲染所有数据组 -->
				<div v-for="(group, groupIndex) in displayGroups" :key="groupIndex" class="data-group">
					<div v-for="(item, itemIndex) in group" :key="itemIndex" class="data-item">
						<view class="topbox">
							<view class="" style="color:#229fff ;">
								{{showNtype[item.ntype] ||'未知类型' }}
							</view>
							<view class="" style="font-size: 26rpx;">
								{{ item.ctime }}
							</view>
						</view>
						<view class="">
							{{ item.content }}
						</view>
						<!-- <span class="item-content">{{ item.content }}</span>
						<span class="item-time">{{ formatTime(item.time) }}</span> -->
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	import request from '../utils/request';
	import apiurl from '../utils/api';
	export default {
		name: 'SeamlessMarquee',
		props: {
			// 传入的数据源，每条数据包含content和time
			// data: {
			// 	type: Array,
			// 	required: true,
			// 	default: () => [],
			// 	validator: (value) => {
			// 		// 验证数据格式是否正确
			// 		return value.every(item =>
			// 			item && typeof item === 'object' &&
			// 			'content' in item && 'ctime' in item
			// 		);
			// 	}
			// },
			// 滚动速度(px/s)
			speed: {
				type: Number,
				default: 60 // 每秒滚动60px
			},
			// 每条数据的高度(px)
			itemHeight: {
				type: Number,
				default: 60
			},
			// 时间格式化方式，可选值：'full'（完整时间）、'time'（仅时间）、'date'（仅日期）
			timeFormat: {
				type: String,
				default: 'time',
				validator: (value) => ['full', 'time', 'date'].includes(value)
			}
		},
		data() {
			return {
				// 原始分组数据
				originalGroups: [],
				// 显示用的分组数据（包含拼接的循环数据）
				displayGroups: [],
				// 当前滚动位置
				scrollPosition: 0,
				// 动画帧ID
				animationFrame: null,
				// 最后一次动画时间
				lastTime: 0,
				// 每组显示的条数
				groupSize: 3,
				data: [],
				ntypeList: [{
					id: 1,
					value: '跟进记录'
				}, {
					id: 2,
					value: '我的任务'
				}, {
					id: 3,
					value: '活动管理'
				}, {
					id: 4,
					value: '动态播报'
				}],
			};
		},
		computed: {
			// 一组数据的总高度
			groupHeight() {
				return this.itemHeight * this.groupSize;
			},
			// 原始数据总高度
			totalOriginalHeight() {
				return this.originalGroups.length * this.groupHeight;
			},
			showNtype() {
				return {
					1: '跟进记录',
					2: '我的任务',
					3: '活动管理',
					4: '动态播报'
				}
			}
		},
		watch: {
			data(newVal) {
				this.processData(newVal);
				this.resetScroll();
			}
		},
		mounted() {
			this.processData(this.data);
			this.startScroll();

			// 鼠标悬停暂停，离开继续
			const viewport = this.$refs.viewport;
			viewport.addEventListener('mouseenter', this.pauseScroll);
			viewport.addEventListener('mouseleave', this.startScroll);
		},
		beforeUnmount() {
			this.stopScroll();
			const viewport = this.$refs.viewport;
			viewport.removeEventListener('mouseenter', this.pauseScroll);
			viewport.removeEventListener('mouseleave', this.startScroll);
		},
		created() {
			this.notificationList()
		},
		methods: {
			notificationList() {
				request(apiurl.notificationList, "GET")
					.then(res => {
						console.log(res);
						this.data = res.rows;
					})
					.catch(err => {
						console.log(err);
					})
			},
			// 处理数据，将数据按3条一组进行分组，不足时循环填充原始数据
			processData(rawData) {
				if (!rawData || rawData.length === 0) {
					this.originalGroups = [];
					this.displayGroups = [];
					return;
				}

				// 复制原始数据避免修改源数据
				const originalData = [...rawData];
				const groups = [];
				let currentGroup = [];
				let dataIndex = 0;
				const totalItemsNeeded = Math.ceil(originalData.length / this.groupSize) * this.groupSize ;

				// 循环填充数据直到满足完整分组的需求
				for (let i = 0; i < totalItemsNeeded; i++) {
					// 当到达数据末尾时，从开头重新开始
					currentGroup.push(originalData[dataIndex % originalData.length]);
					dataIndex++;

					// 当组内数据达到3条时，创建新组
					if (currentGroup.length === this.groupSize) {
						groups.push([...currentGroup]);
						currentGroup = [];
					}
				}

				this.originalGroups = groups;
				// 显示数据是原始数据加上一份完整的原始数据，用于无缝滚动
				this.displayGroups = [...this.originalGroups, ...this.originalGroups];
			},

			// 格式化时间显示
			formatTime(time) {
				// 处理时间戳或日期字符串
				const date = new Date(time);

				// 检查日期是否有效
				if (isNaN(date.getTime())) {
					return 'Invalid time';
				}

				const year = date.getFullYear();
				const month = String(date.getMonth() + 1).padStart(2, '0');
				const day = String(date.getDate()).padStart(2, '0');
				const hours = String(date.getHours()).padStart(2, '0');
				const minutes = String(date.getMinutes()).padStart(2, '0');
				const seconds = String(date.getSeconds()).padStart(2, '0');

				switch (this.timeFormat) {
					case 'full':
						return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
					case 'date':
						return `${year}-${month}-${day}`;
					case 'time':
					default:
						return `${hours}:${minutes}:${seconds}`;
				}
			},

			// 滚动动画函数
			animate(timestamp) {
				if (!this.lastTime) this.lastTime = timestamp;
				const deltaTime = timestamp - this.lastTime;

				// 根据时间差和速度计算滚动距离（单位：px）
				const scrollDistance = (this.speed / 1000) * deltaTime;
				this.scrollPosition += scrollDistance;

				// 当滚动超过一组数据的高度时，检查是否需要重置位置
				if (this.scrollPosition >= this.totalOriginalHeight) {
					// 不是直接跳回，而是计算超出的部分，实现无缝衔接
					this.scrollPosition = this.scrollPosition % this.totalOriginalHeight;
				}

				this.lastTime = timestamp;
				this.animationFrame = requestAnimationFrame(this.animate);
			},

			// 开始滚动
			startScroll() {
				if (!this.animationFrame) {
					this.lastTime = 0;
					this.animationFrame = requestAnimationFrame(this.animate);
				}
			},

			// 暂停滚动
			pauseScroll() {
				if (this.animationFrame) {
					cancelAnimationFrame(this.animationFrame);
					this.animationFrame = null;
				}
			},

			// 停止滚动
			stopScroll() {
				this.pauseScroll();
				this.scrollPosition = 0;
			},

			// 重置滚动
			resetScroll() {
				this.stopScroll();
				this.startScroll();
			}
		}
	};
</script>

<style scoped>
	.marquee-wrapper {
		width: 100%;
		box-sizing: border-box;
	}

	/* 可视区域，固定显示3条数据 */
	.marquee-viewport {
		overflow: hidden;
		/* height: calc(100% - 100rpx); */
		height: 100%;
		/* 3条数据的总高度 */
		position: relative;
		padding: 0 10rpx;
		/* border: 1px solid #e0e0e0; */
		border-radius: 6px;
		box-sizing: border-box;
		/* box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.3); */
	}

	/* 滚动内容区 */
	.marquee-content {
		transition: transform 0s linear;
		/* 关闭CSS过渡，使用JS控制平滑滚动 */
	}

	/* 数据组容器 */
	.data-group {

		/* 一组包含3条数据，高度由itemHeight决定 */
	}

	/* 单条数据样式 */
	.data-item {
		height: 80px;
		/* display: flex;
		align-items: center; */
		padding: 0 16px;
		box-shadow: rgba(17, 17, 26, 0.1) 0px 0px 18rpx;
		border-bottom: 1px solid #f5f5f5;
		background-color: #fff;
		box-sizing: border-box;
		justify-content: space-between;
		border-radius: 20rpx;
		margin-top: 20rpx;
		/* 内容和时间左右分离 */
	}

	.topbox {
	
		width: 100%;
		display: flex;
		flex-flow: row;
		align-items: center;
		justify-content: space-between;
		padding: 10rpx 0;
		border-bottom: 1px solid #b0b0b0;
		color: #b0b0b0;
	}

	/* 内容样式 */
	.item-content {
		flex: 1;
		text-align: left;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		padding-right: 16px;
	}

	/* 时间样式 */
	.item-time {
		color: #888;
		font-size: 14px;
		white-space: nowrap;
	}

	/* 每组最后一条数据去掉下边框 */
	.data-group .data-item:last-child {
		border-bottom: none;
	}

	/* 鼠标悬停效果 */
	.marquee-viewport:hover {
		/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
	}
</style>